use std::cell::RefCell;
use std::rc::Rc;
use super::{ConstantInfo, ClassReader, ConstantPool};


// CONSTANT_Fieldref_info {
// u1 tag; // 值为9
// u2 class_index; // 指向声明字段的类或接口描述符CONSTANT_Class_info的索引
// u2: name_and_type_index; // 指向字段描述符CONSTANT_NameAndType的索引
// }
pub struct ConstantFieldrefInfo {
    cp: Rc<RefCell<ConstantPool>>,
    class_index: usize,
    name_and_type_index: usize
}


impl ConstantInfo for ConstantFieldrefInfo {
    fn read_info(&mut self, reader: &mut ClassReader){
        self.class_index = reader.read_u16().into();
        self.name_and_type_index = reader.read_u16().into();
    }
}

impl ConstantFieldrefInfo {
    pub fn new(cp: Rc<RefCell<ConstantPool>>) -> ConstantFieldrefInfo {
        ConstantFieldrefInfo {
            cp,
            class_index: usize::default(),
            name_and_type_index: usize::default()
        }
    }

    pub fn class_name(&self) -> String {
        self.cp.borrow().get_class_name(self.class_index)
    }

    pub fn name_and_descriptor(&self) -> (String, String) {
        self.cp.borrow().get_name_and_type(self.name_and_type_index)
    }
}

// CONSTANT_Methodref_info {
// u1 tag; // 值为10
// u2 class_index; // 指向声明字段的类或接口描述符CONSTANT_Class_info的索引
// u2: name_and_type_index; // 指向CONSTANT_NameAndType
// }
pub struct ConstantMethodrefInfo {
    cp: Rc<RefCell<ConstantPool>>,
    class_index: usize,
    name_and_type_index: usize
}


impl ConstantInfo for ConstantMethodrefInfo {
    fn read_info(&mut self, reader: &mut ClassReader){
        self.class_index = reader.read_u16().into();
        self.name_and_type_index = reader.read_u16().into();
    }
}

impl ConstantMethodrefInfo {
    pub fn new(cp: Rc<RefCell<ConstantPool>>) -> ConstantMethodrefInfo {
        ConstantMethodrefInfo {
            cp,
            class_index: usize::default(),
            name_and_type_index: usize::default()
        }
    }

    pub fn class_name(&self) -> String {
        self.cp.borrow().get_class_name(self.class_index)
    }

    pub fn name_and_descriptor(&self) -> (String, String) {
        self.cp.borrow().get_name_and_type(self.name_and_type_index)
    }
}

// CONSTANT_InterfaceMethodref_info {
// u1 tag; // 值为11
// u2 class_index; // 指向CONSTANT_Class_info的索引
// u2: name_and_type_index; // 指向CONSTANT_NameAndType
// }
pub struct ConstatnInterfaceMethodrefInfo {
    cp: Rc<RefCell<ConstantPool>>,
    class_index: usize,
    name_and_type_index: usize
}


impl ConstantInfo for ConstatnInterfaceMethodrefInfo {
    fn read_info(&mut self, reader: &mut ClassReader){
        self.class_index = reader.read_u16().into();
        self.name_and_type_index = reader.read_u16().into();
    }
}

impl ConstatnInterfaceMethodrefInfo {
    pub fn new(cp: Rc<RefCell<ConstantPool>>) -> ConstatnInterfaceMethodrefInfo {
        ConstatnInterfaceMethodrefInfo {
            cp,
            class_index: usize::default(),
            name_and_type_index: usize::default()
        }
    }

    pub fn class_name(&self) -> String {
        self.cp.borrow().get_class_name(self.class_index)
    }

    pub fn name_and_descriptor(&self) -> (String, String) {
        self.cp.borrow().get_name_and_type(self.name_and_type_index)
    }
}